package top.cardone.data.mybatisplus.service;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public interface MybatisPlusService<T> {
    /**
     * 插入一条记录（选择字段，策略插入）
     *
     * @param entity 实体对象
     */
    @CacheEvict(allEntries = true)
    default boolean saveCache(T entity) {
        return this.save(entity);
    }

    /**
     * 插入一条记录（选择字段，策略插入）
     *
     * @param entity 实体对象
     */
    boolean save(T entity);

    /**
     * 插入（批量）
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    @CacheEvict(allEntries = true)
    default boolean saveBatchCache(Collection<T> entityList) {
        return this.saveBatch(entityList);
    }

    /**
     * 插入（批量）
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    boolean saveBatch(Collection<T> entityList);

    /**
     * 批量插入
     *
     * @param entityList ignore
     * @param batchSize  ignore
     * @return ignore
     */
    @CacheEvict(allEntries = true)
    @Transactional
    default boolean saveBatchCache(Collection<T> entityList, int batchSize) {
        return this.saveBatch(entityList, batchSize);
    }

    /**
     * 批量插入
     *
     * @param entityList ignore
     * @param batchSize  ignore
     * @return ignore
     */
    @Transactional
    boolean saveBatch(Collection<T> entityList, int batchSize);

    /**
     * TableId 注解存在更新记录，否插入一条记录
     *
     * @param entity 实体对象
     * @return boolean
     */
    @Transactional
    @CacheEvict(allEntries = true)
    default boolean saveOrUpdateCache(T entity) {
        return this.saveOrUpdate(entity);
    }

    /**
     * TableId 注解存在更新记录，否插入一条记录
     *
     * @param entity 实体对象
     * @return boolean
     */
    @Transactional
    boolean saveOrUpdate(T entity);

    /**
     * 批量修改插入
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    @CacheEvict(allEntries = true)
    default boolean saveOrUpdateBatchCache(Collection<T> entityList) {
        return this.saveOrUpdateBatch(entityList);
    }

    /**
     * 批量修改插入
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    boolean saveOrUpdateBatch(Collection<T> entityList);

    /**
     * 批量修改插入
     *
     * @param entityList
     * @param batchSize
     * @return
     */
    @Transactional
    @CacheEvict(allEntries = true)
    default boolean saveOrUpdateBatchCache(Collection<T> entityList, int batchSize) {
        return this.saveOrUpdateBatch(entityList, batchSize);
    }

    /**
     * 批量修改插入
     *
     * @param entityList
     * @param batchSize
     * @return
     */
    @Transactional
    boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    @CacheEvict(allEntries = true)
    default boolean removeByIdCache(Serializable id) {
        return this.removeById(id);
    }

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    boolean removeById(Serializable id);

    /**
     * 根据 columnMap 条件，删除记录
     *
     * @param columnMap 表字段 map 对象
     */
    @CacheEvict(allEntries = true)
    default boolean removeByMapCache(Map<String, Object> columnMap) {
        return this.removeByMap(columnMap);
    }

    /**
     * 根据 columnMap 条件，删除记录
     *
     * @param columnMap 表字段 map 对象
     */
    boolean removeByMap(Map<String, Object> columnMap);

    /**
     * 删除（根据ID 批量删除）
     *
     * @param idList 主键ID列表
     */
    @CacheEvict(allEntries = true)
    default boolean removeByIdsCache(Collection<?> idList) {
        return this.removeByIds(idList);
    }

    /**
     * 删除（根据ID 批量删除）
     *
     * @param idList 主键ID列表
     */
    boolean removeByIds(Collection<?> idList);

    /**
     * 根据 ID 选择修改
     *
     * @param entity 实体对象
     */
    @CacheEvict(allEntries = true)
    default boolean updateByIdCache(T entity) {
        return this.updateById(entity);
    }

    /**
     * 根据 ID 选择修改
     *
     * @param entity 实体对象
     */
    boolean updateById(T entity);

    /**
     * 根据ID 批量更新
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    @CacheEvict(allEntries = true)
    default boolean updateBatchByIdCache(Collection<T> entityList) {
        return this.updateBatchById(entityList);
    }

    /**
     * 根据ID 批量更新
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    boolean updateBatchById(Collection<T> entityList);

    /**
     * 根据ID 批量更新
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    @CacheEvict(allEntries = true)
    default boolean updateBatchByIdCache(Collection<T> entityList, int batchSize) {
        return this.updateBatchById(entityList, batchSize);
    }

    /**
     * 根据ID 批量更新
     *
     * @param entityList 实体对象集合
     */
    @Transactional
    boolean updateBatchById(Collection<T> entityList, int batchSize);

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    @Cacheable
    default T getByIdCache(Serializable id) {
        return this.getById(id);
    }

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    T getById(Serializable id);

    /**
     * 查询（根据ID 批量查询）
     *
     * @param idList 主键ID列表
     */
    @Cacheable
    default List<T> listByIdsCache(Collection<? extends Serializable> idList) {
        return this.listByIds(idList);
    }

    /**
     * 查询（根据ID 批量查询）
     *
     * @param idList 主键ID列表
     */
    List<T> listByIds(Collection<? extends Serializable> idList);

    /**
     * 查询（根据 columnMap 条件）
     *
     * @param columnMap 表字段 map 对象
     */
    @Cacheable
    default List<T> listByMapCache(Map<String, Object> columnMap) {
        return this.listByMap(columnMap);
    }

    /**
     * 查询（根据 columnMap 条件）
     *
     * @param columnMap 表字段 map 对象
     */
    List<T> listByMap(Map<String, Object> columnMap);

    /**
     * 查询总记录数
     */
    @Cacheable
    default Long countCache() {
        return this.count();
    }

    /**
     * 查询总记录数
     */
    long count();

    /**
     * 查询总记录数
     */
    @Cacheable
    default long countCache(Map<String, Object> param) {
        return this.count(param);
    }

    /**
     * 查询总记录数
     */
    default long count(Map<String, Object> param) {
        return this.count();
    }

    /**
     * 查询所有
     */
    @Cacheable
    default List<T> listCache() {
        return this.list();
    }

    /**
     * 查询所有
     */
    List<T> list();

    /**
     * 查询所有
     */
    @Cacheable
    default List<T> listCache(Map<String, Object> param) {
        return this.list(param);
    }

    /**
     * 查询所有
     */
    default List<T> list(Map<String, Object> param) {
        return this.list();
    }

    /**
     * 无条件翻页查询
     *
     * @param param 翻页对象
     */
    @Cacheable
    default <E extends Page<T>> E pageCache(Map<String, Object> param) {
        return this.page(param);
    }

    /**
     * 无条件翻页查询
     *
     * @param param 翻页对象
     */
    <E extends Page<T>> E page(Map<String, Object> param);

    /**
     * 查询所有列表
     */
    @Cacheable
    default List<Map<String, Object>> listMapsCache() {
        return this.listMaps();
    }

    /**
     * 查询所有列表
     */
    List<Map<String, Object>> listMaps();

    /**
     * 查询列表
     */
    @Cacheable
    default List<Map<String, Object>> listMapsCache(Map<String, Object> param) {
        return this.listMaps(param);
    }

    /**
     * 查询列表
     */
    default List<Map<String, Object>> listMaps(Map<String, Object> param) {
        return this.listMaps();
    }

    /**
     * 查询全部记录
     */
    @Cacheable
    default List<Object> listObjsCache() {
        return this.listObjs();
    }

    /**
     * 查询全部记录
     */
    List<Object> listObjs();

    /**
     * 查询记录
     */
    @Cacheable
    default List<Object> listObjsCache(Map<String, Object> param) {
        return this.listObjs(param);
    }

    /**
     * 查询记录
     */
    default List<Object> listObjs(Map<String, Object> param) {
        return this.listObjs();
    }

    /**
     * 无条件翻页查询
     *
     * @param param 翻页对象
     */
    @Cacheable
    default <E extends Page<Map<String, Object>>> E pageMapsCache(Map<String, Object> param) {
        return this.pageMaps(param);
    }

    /**
     * 无条件翻页查询
     *
     * @param param 翻页对象
     */
    <E extends Page<Map<String, Object>>> E pageMaps(Map<String, Object> param);
}
